package jmine.tec.rtm.impl.web.pages.diagnosticador;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Locale;

import jmine.tec.web.wicket.resource.DiskStoreResource;
import jmine.tec.web.wicket.resource.InMemoryResourceStore;
import jmine.tec.web.wicket.resource.ResourceStore;

import org.apache.wicket.util.resource.IResourceStream;
import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
import org.apache.wicket.util.time.Time;

import bancosys.tec.rtm.diagnostician.Diagnostician;
import bancosys.tec.rtm.diagnostician.report.text.DiagnosticianReportGeneratorText;
import bancosys.tec.rtm.impl.RtmController;
import bancosys.tec.rtm.impl.diagnostician.SimpleDiagnosticianCase;

/**
 * @author takeshi
 */
public class DiagnosticadorResourceStream implements IResourceStream {

    private InputStream input;

    private Locale locale;

    private final Time time = Time.now();

    private ResourceStore resourceStore;

    private final List<Diagnostician> diagnosticadores;

    private RtmController controller;

    /**
     * Construtor.
     * 
     * @param diagnosticadores diagnosticadores
     * @param controller controller
     */
    public DiagnosticadorResourceStream(List<Diagnostician> diagnosticadores, RtmController controller) {
        this.diagnosticadores = diagnosticadores;
        this.controller = controller;
    }

    /**
     * {@inheritDoc}
     */
    public void close() throws IOException {
        try {
            this.input.close();
        } finally {
            this.input = null;
        }
    }

    /**
     * Devolve o report 'as is'
     * 
     * @return InputStream
     */
    private InputStream getDiagnostico() {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        try {
            SimpleDiagnosticianCase diagnosticianCase = new SimpleDiagnosticianCase(this.diagnosticadores);
            diagnosticianCase.executeDiagnosticianInDebugMode(new DiagnosticianReportGeneratorText(), bout);
        } catch (Exception e) {
            this.controller.monitor(e);
            throw new IllegalStateException(e);
        }
        return new ByteArrayInputStream(bout.toByteArray());
    }

    /**
     * 
     */
    public synchronized void init() {
        if (this.resourceStore != null) {
            return;
        }
        try {
            this.resourceStore = new DiskStoreResource(this.getDiagnostico(), true);
        } catch (IOException e) {
            try {
                this.resourceStore = new InMemoryResourceStore(this.getDiagnostico(), false);
            } catch (IOException e1) {
                throw new IllegalStateException(e);
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public String getContentType() {
        return "text/plain";
    }

    /**
     * {@inheritDoc}
     */
    public InputStream getInputStream() throws ResourceStreamNotFoundException {
        if (this.input != null) {
            return this.input;
        }
        this.init();
        try {
            this.input = this.resourceStore.openNew();
            return this.input;
        } catch (IOException e) {
            return this.getDiagnostico();
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.apache.wicket.util.resource.IResourceStream#length()
     */
    public long length() {
        this.init();
        return this.resourceStore.length();
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.apache.wicket.util.watch.IModifiable#lastModifiedTime()
     */
    public Time lastModifiedTime() {
        return this.time;
    }

    /**
     * @return the locale
     */
    public Locale getLocale() {
        return this.locale;
    }

    /**
     * @param locale the locale to set
     */
    public void setLocale(Locale locale) {
        this.locale = locale;
    }

}
